var request = require('request');
var log = require('../../common/log').log;
var server = {};
exports.server = server;

/**
 * 本方法对普通request请求做了封装，将请求是否成功的逻辑放到此方法，同时处理错误以及写入日志。
 * 
 * @param {object} req 请求对象 【必填】
 * @param {object} res 响应对象 【必填】
 * @param {object} body 请求体，即请求接口的参数 【必填】
 * @param {string} message 请求说明 【选填】
 * @param {function} success 请求成功的回调 【必填】
 * @param {string} successBy 用作判断请求是否成功的字段，默认为succeed【选填】
 * @param {string} successValue 判断请求是否成功的字段的值，默认为true【选填】
 * @param {function} fail 请求失败的回调【选填】
 * @param {string} failCode 请求失败的错误码字段名，默认为errmsg【选填】
 * @param {string} failMsg 请求失败的错误信息字段名，默认为msg【选填】
 * @param {string} failPage 请求失败时，渲染的页面，默认为error.html【选填】
 * @param {function} error 请求出错的回调【选填】
 * @param {string} errorPage 请求出错时，渲染的页面，默认为error.html【选填】
 * @param {string} errorMsg 请求出错时的提示信息，默认为"服务器异常"【选填】
 * @param {boolean} type 当未自定义请求失败或出错的回调，以何种方式处理错误，支持json和render，默认为渲染错误页面，即render 【选填】
 */
server.request = function (obj) {
    var option = {
        req: obj.req,
        res: obj.res,
        body: obj.body,
        message: obj.message,
        success: obj.success,
        successKey: obj.successKey || "succeed",
        successValue: obj.successValue || true,
        fail: obj.fail,
        failCode: obj.failCode || "errmsg",
        failMsg: obj.failMsg || "msg",
        failPage: obj.failPage || "error",
        error: obj.error,
        errorPage: obj.errorPage || "error",
        errorMsg: obj.errorMsg || "服务器异常",
        type: obj.type || "render"
    }

    /**
     * request请求回调函数
     * 
     * @param {any} error
     * @param {any} response
     * @param {any} body 
     * @returns 
     */
    function callback(error, response, body) {
        var status = response && response.statusCode;
        if (!error && status == 200) {
            console.info("==========" + option.message + "==========", "\n请求参数=>", JSON.stringify(option.body), "\n接口返回=>", JSON.stringify(body));
            var data = JSON.parse(body);
            // if (data[option.successKey] == option.successValue) {
                //请求成功
                option.success(data);

                //写入成功日志
                //log.writeLog("Info", option.req, option.message, option.body, data);
            // } else {
            //     //写入失败日志
            //     log.writeLog("Error", option.req, option.message, option.body, data);

            //     //处理错误
            //     errorHandler(option.fail, option.type, data[option.failCode], data[option.failMsg], null, option.failPage);
            // }
        } else {
            //写入错误日志
            log.writeLog("Fatal", option.req, option.message, option.body, {error: error, response: response});

            //处理错误
            errorHandler(option.error, option.type, null, option.errorMsg, status, option.errorPage);
        }
    }

    /**
     * 错误处理方法，先判断是否存在自定义错误处理函数，有则执行，否则执行默认错误回调。
     * 
     * @param {any} fn 自定义错误处理函数
     * @param {any} type 以什么方式处理错误，支持render或json
     * @param {any} code 接口返回的状态码字段
     * @param {any} msg 接口返回的信息字段
     * @param {any} page 出错时渲染的视图文件名
     * @returns 
     */
    function errorHandler(fn, type, code, msg, status, page) {
        if (!isFunction(fn)) {
            //执行默认请求出错回调，渲染错误页面，或以json返回错误信息
            var data = {
                error: status || code,
                message: msg
            };
            var result = type === "render" ? option.res[type](page, data) : option.res[type](data);
            return result;
        } else {
            //执行自定义请求出错回调
            fn();
        }
    }

    /**
     * 判断是否为function
     * 
     * @param {any} fn 
     * @returns 
     */
    function isFunction(fn) {
        return Object.prototype.toString.call(fn) === '[object Function]';
    }
    request(option.body, callback);
};